package com.zifan.sever.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zifan.sever.bean.Employee;
import com.zifan.sever.bean.MailLog;
import com.zifan.sever.constant.MailConstants;
import com.zifan.sever.mapper.EmployeeMapper;
import com.zifan.sever.service.IMailLogService;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 确保邮件投递成功 3 定时任务
 * @author Zifan
 * @date 2021年05月20日20:31
 */
@Component
public class MailTask {

    @Autowired
    private IMailLogService mailLogServicel;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 邮件定时任务
     * 十秒执行一次
     * 具体的业务逻辑是这样的：
     * 首先每十秒查询一次数据库，查询MailLog表中状态为0（发送中）且重试时间大于当前时间的，因为设在创建这条数据后设置的是如果失败一分钟后才重试
     * 然后循环查询出来的列表，
     * 如果重试次数超过三，修改状态为失败，不在重试（这里应该直接return）
     * 否则 重试次数加一，重设下次重试时间为一分钟以后。更新这条数据，之后重新向mq发送
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void mailTask(){
        //这是，如果当前当前时间小于重试时间的话，那就不重发！也就是说，如果重试时间在三分钟后，拿在这三分钟内就一直不重发。
        QueryWrapper<MailLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status",0);
        queryWrapper.lt("tryTime", LocalDateTime.now());
        List<MailLog> mailLogs = mailLogServicel.list(queryWrapper);
        for (MailLog mailLog : mailLogs) {
            //如果重试次数超过三次，那么投递状态更改为失败，不在重试
            if (3<=mailLog.getCount()){
                UpdateWrapper<MailLog> updateWrapper = new UpdateWrapper<>();
                updateWrapper.set("status",2).eq("msgId",mailLog.getMsgId());
                mailLogServicel.update(updateWrapper);
            }
            //更新maillog，把重试次数+1，然后重设设置下次重试时间。更新重试次数
            mailLogServicel.update(new UpdateWrapper<MailLog>().eq("msgId",mailLog.getMsgId())
                    .set("count",mailLog.getCount()+1).set("updateTime",LocalDateTime.now())
            .set("tryTime", LocalDateTime.now().plusMinutes(MailConstants.MSG_TIMEOUT)));
            //重新根据员工id获取员工信息，准备发邮件
            Employee employee = employeeMapper.getEmployees(mailLog.getEid()).get(0);
            //向队列中发送
            rabbitTemplate.convertAndSend(
                    MailConstants.MAIL_EXCHANGE_NAME,
                    MailConstants.MAIL_ROUTING_KEY_NAME,
                    employee,
                    new CorrelationData(mailLog.getMsgId()));
        }
    }
}
